/**
 * 解析路由
 */
import errorCatch from '../entrance/event/errorCatch';
import controRoute from './RouterHandler';
import ConfigHandler from '../init/ConfigHandler';
import { parsPlug } from "../entrance/plug";
import Middleware from '../middleware/middleware';
import RequestType from '../model/RequestType';
import { exit } from 'process';

export = RouterPars;
class RouterPars {
  //初始化路由
  public static async init() {
    // 给全局中间件赋值 每次调用此方法都更新一次全局中间件
    controRoute.setGlobalMiddleware(ConfigHandler.getGlobal_Middleware())

    // 解析并设置全局中间件
    await Promise.all(ConfigHandler.getRouteConfig().map(async (item:routeFile)=>{
      let file: string = item.path;
      if (!file) {
        console.log("路由文件路径不可为空");
        exit();
      }
      //运行路由文件
      await this.runRouteFile(file);
    }))

    //合并路由文件的内容
    await this.mergeRout();

    // 解析特殊接口
    await this.special(ConfigHandler.getSpecial() as speciaConfig);
    // 解析扩展
    parsPlug()
  }

  //运行一个路由文件
  public static async runRouteFile(filepath: string) {
    try {
      // 使用加载器加载路由文件
      await global.loader(filepath, true);
    } catch (err) {
      errorCatch(err)
    }
  }

  //合并路由文件
  public static async mergeRout() {
    controRoute.setStaticRoute(this.Object_merge(controRoute.getUnStaticRoute() as unrouteStructure));
    controRoute.setDynamicRoute(this.Object_merge(controRoute.getUnDynamicRoute() as unrouteStructure));
  }


  //合并两个对象，内容相同合并，不同则添加
  public static Object_merge(objarr: unrouteStructure): routeStructure {
    // 创建 get post any
    let obj: routeStructure = new RequestType();
    Object.keys(objarr).forEach(filepath => {
      Object.keys(objarr[filepath]).forEach(type => {
        Object.keys(objarr[filepath][type]).forEach(url => {
          // get post any 都合并起来
          obj[type][url] = objarr[filepath][type][url];
        })
      })
    })
    return obj;
  }


  // 解析特殊接口
  public static async special(specialConfig: speciaConfig) {
    // 解析方法
    let pars = async (name: string, mes: string) => {
      // 先判断下用户代码上有没有设置特殊接口
      if (!controRoute.getSpecialRoute(name)) {
        // 默认配置中有这些接口的配置 用户的配置会覆盖默认的配置
        let inter: specialInter = ConfigHandler.getSpecial(name) as specialInter;
        let controller = Middleware.pars_string_middleware(inter.path, name, inter.parameter || [])
        controRoute.addSpecialRoute(name, {
          modules: [],
          controller: controller
        })
      }
    }

    // 初始化特殊接口 如果用户自定义了特殊接口，那就不做更改 ，如果没有自定义，那就设置默认的接口
    for (let name in specialConfig) {
      await pars(name, name + " 未设置路由");
    }
  }

}
